#include <stdio.h>
#include <errno.h>
#include <assert.h>
#ifndef _WIN32
#include <pthread.h>
#endif//_WIN32

#include "SilmLogApi.h"
#include "SilmLog.h"
#include "SilmLogUtil.h"

#ifdef __cplusplus
extern "C" {
#endif//__cplusplus
   
    static CSilmLog *g_log = NULL;
#ifdef _WIN32
    static CRITICAL_SECTION g_lock = {0};

#define LOCK(l)         EnterCriticalSection((l))
#define UNLOCK(l)       LeaveCriticalSection((l))
#else
    static pthread_mutex_t g_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

#define LOCK(l)         pthread_mutex_lock((l))
#define UNLOCK(l)       pthread_mutex_unlock((l))
#endif//_WIN32

    int SILMLOG_API SilmLogInit(IN unsigned int version, IN unsigned int bitmap, IN const char *pLogFilename)
    {
        int ret = 0;

        if (version != SILM_LOG_VERSION(SILM_LOG_VERSION_MAJOR, SILM_LOG_VERSION_MINOR))
        {
            UtilSysLog(SILM_LOG_TYPE_ERROR, "SilmLog version not match!version(%u.%u) dll(%u.%u)\n",
                SILM_LOG_GETVER_MAJOR(version), SILM_LOG_GETVER_MINOR(version), SILM_LOG_VERSION_MAJOR, SILM_LOG_VERSION_MINOR);
            return EINVAL;
        }
        if ((!(SILM_LOG_INIT_BITMAP_SYS & bitmap) && !(SILM_LOG_INIT_BITMAP_FILE & bitmap))
            || ((SILM_LOG_INIT_BITMAP_FILE & bitmap) && (NULL == pLogFilename)))
        {
            UtilSysLog(SILM_LOG_TYPE_ERROR, "SilmLog initialize parameter is invalid!\n");
            return EINVAL;
        }
        if (NULL == g_log)
        {
#ifdef _WIN32
            InitializeCriticalSection(&g_lock);
#endif//_WIN32
            g_log = new CSilmLog();
            ret = g_log->Initialize(bitmap, pLogFilename);
            if (0 != ret)
            {
                delete g_log;
                g_log = NULL;
#ifdef _WIN32
                DeleteCriticalSection(&g_lock);
#endif//_WIN32
            }
        }
        return ret;
    }

    void SILMLOG_API SilmLogUnInit(void)
    {
        if (NULL != g_log)
        {
            delete g_log;
            g_log = NULL;
#ifdef _WIN32
            DeleteCriticalSection(&g_lock);
#endif//_WIN32
        }
    }

    int SILMLOG_API SilmLogWrite(IN unsigned int logType, IN const char *format, ...)
    {
        int ret;
        va_list args;

        assert(NULL != g_log);

        LOCK(&g_lock);
        va_start(args, format);
        ret = g_log->WriteLog(logType, format, args);
        va_end(args);
        UNLOCK(&g_lock);
        return ret;
    }

#ifdef __cplusplus
};

#endif//__cplusplus
